package org.datascooter.cglib.proxy.impl;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.datascooter.bundle.DSMapper;
import org.datascooter.bundle.attribute.ContainerAttribute;
import org.datascooter.cglib.proxy.ObjectWrapper;
import org.datascooter.cglib.proxy.SimpleInterceptor;
import org.datascooter.exception.EntityNotMappedException;
import org.datascooter.inface.IDataManager;

public class ProxyMap<K, V> extends SimpleInterceptor implements Map<K, V> {

	private static final long serialVersionUID = -5171844524312240955L;
	private ContainerAttribute attribute;
	private Map<K, V> map;

	public ProxyMap(SimpleInterceptor parent, Object container, String containerAttribute, IDataManager dataManager) throws EntityNotMappedException, SecurityException, NoSuchMethodException {
		super(parent, container, containerAttribute, dataManager);
		attribute = DSMapper.getBundle(container.getClass().getName()).getContainerAttribute(containerAttribute);
	}

	@Override
	public Object getSource() {
		return map;
	}

	@Override
	protected void saveContent(String attributeName, Object[] args) throws EntityNotMappedException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException {
		crossProvider.saveContent(container, attributeName, args[1]);
		map.put((K) args[0], (V) args[1]);
	}

	@Override
	public void setContainer(Object object) {
		container = object;
		map = new HashMap<K, V>();
		List<Object> content = crossProvider.getContent(container, containerAttribute);
		for (Object item : content) {
			try {
				ObjectWrapper.wrap(manager, item);
				map.put((K) attribute.getValue(item), (V) item);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public int size() {
		return map.size();
	}

	public boolean isEmpty() {
		return map.isEmpty();
	}

	public boolean containsKey(Object key) {
		return map.containsKey(key);
	}

	public boolean containsValue(Object value) {
		return map.containsValue(value);
	}

	public V get(Object key) {
		return map.get(key);
	}

	public V put(K key, V value) {
		return map.put(key, value);
	}

	public V remove(Object key) {
		return map.remove(key);
	}

	public void putAll(Map<? extends K, ? extends V> m) {
		map.putAll(m);
	}

	public void clear() {
		map.clear();
	}

	public Set<K> keySet() {
		return map.keySet();
	}

	public Collection<V> values() {
		return map.values();
	}

	public Set<java.util.Map.Entry<K, V>> entrySet() {
		return map.entrySet();
	}

	public boolean equals(Object o) {
		return map.equals(o);
	}

	public int hashCode() {
		return map.hashCode();
	}
}
